package models;

import java.util.Arrays;
import java.util.Random;

import models.msgs.AllIn;
import models.msgs.AreYouBankrupt;
import models.msgs.Bankrupt;
import models.msgs.Bet;
import models.msgs.BuyIn;
import models.msgs.Call;
import models.msgs.Check;
import models.msgs.CollectBuyIn;
import models.msgs.Cards;
import models.msgs.CardsAfterExchange;
import models.msgs.CardsToExchange;
import models.msgs.Cash;
import models.msgs.ExchangeCards;
import models.msgs.Fold;
import models.msgs.Info;
import models.msgs.MyCards;
import models.msgs.OptionsOfBetting;
import models.msgs.Prize;
import models.msgs.Raise;
import models.msgs.ShowMeCards;
import play.mvc.WebSocket;
import akka.actor.ActorRef;

import com.fasterxml.jackson.databind.JsonNode;

public class Bot extends Player {
    public final ActorRef             table;

    protected WebSocket.In<JsonNode>  in;
    protected WebSocket.Out<JsonNode> out;
    
	public Bot(String _name, ActorRef _table) {
        name = _name;        
        table = _table;
		numberOfWin=0;
	}
	
	@Override
	public void onReceive(Object msg) throws Exception {
		if(msg instanceof Cards) {
        	this.cards = ((Cards)msg).getCards();
        	Arrays.sort(this.cards);
        } else if (msg instanceof ExchangeCards) {
   
        	table.tell(new CardsToExchange(wymienKarty()), getSelf());
        } if (msg instanceof CardsAfterExchange) {
        	CardsAfterExchange message = (CardsAfterExchange) msg;
        	updateCards(message.getCards());
        	
        
        } else if(msg instanceof Cash) {
        	myCash = ((Cash)msg).getCash();
        	
        } else if(msg instanceof CollectBuyIn) {
        	CollectBuyIn buyin = ((CollectBuyIn)msg);
        	myCash-=buyin.getBuyIn();
        	getSender().tell(new BuyIn(buyin.getBuyIn(),name), getSelf());
        } else if(msg instanceof OptionsOfBetting) {
        	OptionsOfBetting bo = ((OptionsOfBetting)msg);
        	getSender().tell(bets(bo.getBettingOptions(),bo.getLastBet()), getSelf());
        } else if(msg instanceof Prize) {
        	Prize prize = (Prize)msg;
        	myCash+=prize.getPrize();
        	String tmp = "";
        	for (int i=0; i<5; i++){
        		tmp+=cards[i] + " ";
        	}
            numberOfWin++;
        	tmp+=SprawdzUklad.jakiUklad(cards);
        	table.tell(new Info("I won "+tmp,name), getSelf());
        } else if(msg instanceof ShowMeCards) {
        	getSender().tell(new MyCards(name,cards),getSelf());
        } else if(msg instanceof AreYouBankrupt) {
        	Bankrupt bankrupt = new Bankrupt(name,myCash,numberOfWin);
        	table.tell(bankrupt, getSelf());
        } 
        
		else {
			unhandled(msg);
		}
	}
	
	private Object bets(boolean[] options,int lastBet) {
		Object obj;
		if (myCash <= lastBet+100) {	
			obj = new AllIn(name,myCash);  table.tell(new Info("All-in "+myCash,name), getSelf()); myCash = 0;
			return obj;
		}
		int mov;
		Random rand = new Random();
		
		mov = rand.nextInt(6);
		while(options[mov] == false) {
			mov = rand.nextInt(6);
		}
		switch (mov) {
		case 0 : obj = new Bet(name, 100); myCash-=100; table.tell(new Info("Bet 100",name), getSelf()); break;
		case 1 : obj = new Check(name); table.tell(new Info("Check",name), getSelf()); break;
		case 2 : obj = new Raise(name, lastBet+100); myCash-=(lastBet+100); table.tell(new Info("Raise "+(lastBet+100),name), getSelf()); break;
		case 3 : obj = new Call(name,lastBet);  table.tell(new Info("Call "+lastBet,name), getSelf()); myCash-=lastBet; break;
		case 4 : obj = new Fold(name); table.tell(new Info("Fold",name), getSelf());break;
		default: obj = new AllIn(name,myCash);  table.tell(new Info("All-in "+myCash,name), getSelf()); myCash = 0; break;
		} 
		return obj;
	}
	
    private final Karta[] wymienKarty() {
        Random rand = new Random();
        int ileKart = rand.nextInt(6);
        Karta[] doZwrotu = new Karta[ileKart];
         
        boolean[] czyWymienione = new boolean[5];
        
        for (int i = 0; i < ileKart; i++) {
            int n = rand.nextInt(5);
            if (!czyWymienione[n]) {
                czyWymienione[n] = true;
                doZwrotu[i] = cards[n];
                cards[n] = null;
            } else {
                i--;
            }
        }
        return doZwrotu;
    }
}